#include "openmove_Prefix.h"
#include "SceneBase.h"
#include "OgreEngine.h"
#include "ExampleFrameListener.h"
#include "SkeletalAnimationFrameListener.h"
#include "OgreExternalTextureSourceManager.h"
#include "OgreExternalTextureSource.h"
#include "ScenePetitPot.h"
#include "SimpleFrameListener.h"

CScenePetitPot :: CScenePetitPot(COgreEngine &Creator, const String & Name, const int pos) : CSceneBase(Creator, Name, pos), m_pPluie(NULL), m_pPluieTop(NULL), m_WindSpeed(1)
{
}

CScenePetitPot :: ~CScenePetitPot(void)
{
}

void CScenePetitPot :: Create(TCreatorEntities const &CreatorEntities, TCreatorNodes const &CreatorNodes, TCreatorLights const &CreatorLights, ENetConfig IsClient, Vector3 &CameraStartPos)
{
	CSceneBase::Create(CreatorEntities, CreatorNodes, CreatorLights, IsClient, CameraStartPos);

	//m_OgreEngine.m_pCurrentSceneManager->setSkyBox(true, "SkyBox/petit_pot");

	//Plane plane; 
	//plane.d = 5000;
	//plane.normal = -Vector3::UNIT_Y; 
	//m_OgreEngine.m_pCurrentSceneManager->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3,true,0.0001);

	AddSpotlight("PetitPotspotLight1", 
		Vector3(169.0101, 270.0179, -026.3710),
		-67.200058, -96.800087, 0
		);

	AddSpotlight("PetitPotspotLight2", 
		Vector3(024.9903, 263.1995, -293.1003),
		-82.200073, -68.000061, 0
		);

	AddSpotlight("PetitPotspotLight3", 
		Vector3(070.9345, 238.6815, -018.2585),
		-61.200054, 21.200018, 0, false
		);

	AddSpotlight("PetitPotspotLight4", 
		Vector3(153.9600, 272.8673, -284.0438),
		-57.600052, -66.800056, 0
		);

	AddSpotlight("PetitPotspotLight5", 
		Vector3(202.2690, 208.4274, 135.6411),
		-52.800045, -70.000061, 0
		);

	AddSpotlight("PetitPotspotLight6", 
		Vector3(-407.9143, 219.3104, 039.3623),
		-61.200054, -44.400040, 0, false
		);

	AddSpotlight("PetitPotspotLight7", 
		Vector3(-179.1897, 273.2876, -060.3434),
		-85.200073, 96.800087, 0, false
		);

	AddSpotlight("PetitPotspotLight8", 
		Vector3(-021.6299, 276.4507, -259.0789),
		-57.600052, -66.800056, 0
		);

	AddSpotlight("PetitPotspotLight9", 
		Vector3(051.5795, 206.6047, 051.8318),
		-61.200054, 21.200018, 0, true
		);

	AddSpotlight("PetitPotspotLight10", 
		Vector3(939.8096, 621.1230, -303.0137),
		-59.400051, 5.600005, 0
		);

	AddSpotlight("PetitPotspotLight11", 
		Vector3(1122.0570, 606.7708, 708.3506),
		-63.600056	, 24.800022, 0
		);
	
	AddSpotlight("PetitPotspotLight12", 
		Vector3(204.6491, 664.6538, 457.8334),
		-61.200054, -180.800156, 0
		);

	AddSpotlight("PetitPotspotLight13", 
		Vector3(-169.2514, 729.0544, 318.6765),
		-71.400063, -200.800171, 0
		);

	AddSpotlight("PetitPotspotLight14", 
		Vector3(-203.1956, 800.7999, 224.6474),
		-40.800037, -198.400177, 0
		);

}


bool CScenePetitPot :: frameStarted(const FrameEvent& evt)
{
	CSceneBase::frameStarted(evt);

	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_Z) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_PP_IncWind, 0);
	}
	else
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_X) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_PP_DecWind, 0);
	}
	else
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_C) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_PP_SetWind, 20, String("300 0 0"));
		m_pCameraFrameListener->mTimeUntilNextToggle = 1.0f;
	}
	else
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_V) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_PP_SetWind, 20, String("0 -100 0"));
		m_pCameraFrameListener->mTimeUntilNextToggle = 1.0f;
	}
	else
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_B) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_PP_SetWind, 1, StringConverter::toString(Math::RangeRandom(1.0f, 600.0f)));
		m_pCameraFrameListener->mTimeUntilNextToggle = 1.0f;
	}

	updateParticleSystems();
	m_OgreEngine.setDebugText("m_WindForce: " + StringConverter::toString(m_WindForce));

	return (true);
}

void CScenePetitPot :: AddSpotlight(String const &name, Vector3 const &position, Real const &xAngle, Real const &yAngle, Real const &zAngle, bool const CastShadow)
{
	SceneLight light;
	light.m_Name = name;
	light.setType(Light::LT_SPOTLIGHT);
	//light.setDiffuseColour(0.533000, 0.827132, 1.000000);
	//light.setDiffuseColour(0.266500, 0.413566, 0.500000);
	//light.setDiffuseColour(0.133250, 0.2065, 0.250000);
	light.setDiffuseColour(0.177666, 0.275710, 0.333333);
	light.setCastShadows(CastShadow);
	light.setAttenuation(1000, 1, 0, 0);
	light.setSpotlightInnerAngle(Degree(80.959));
	light.setSpotlightOuterAngle(Degree(93.959));
	light.setSpotlightFalloff(1);

	Vector3 vec = -Vector3::UNIT_Z;
	Quaternion rot = Quaternion(Degree(zAngle), Vector3(0, 0, 1)) * Quaternion(Degree(yAngle), Vector3(0, 1, 0)) * Quaternion(Degree(xAngle), Vector3(1, 0, 0));
	Matrix3 rotMat;
	rot.ToRotationMatrix(rotMat);
	vec = rotMat * vec;
	light.setDirection(vec);
	light.setPosition(position);

	//m_Lights.push_back(pLight);
	m_SceneLights.push_back(light);

	if (m_ShowEntitiesBBox)
	{
		Entity *entity = m_OgreEngine.m_pCurrentSceneManager->createEntity(name, "light.mesh");
		SceneNode *node = m_pSceneNode->createChildSceneNode(name);
		node->setPosition(light.getPosition());
		node->rotate(rot);
		node->scale(10, 10, 10);
		node->attachObject(entity);
	}
}

void CScenePetitPot :: Attach(void)
{
	CSceneBase::Attach();
	//m_pCurrentCamera->setPosition(-180.8f, 87.7f, 452.3f);
	//Quaternion Quat(Radian(Degree(0.0f)), Vector3(0, 1, 0));
	//m_pCurrentCamera->setOrientation(Quat);
	//m_pCurrentCamera->setDirection(0, 0, -1);
	m_OgreEngine.m_pViewPort->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f, 1.0f));
	
	m_OgreEngine.m_pCurrentSceneManager->setSkyBox(true, "SkyBox/PetitPot");

	m_OgreEngine.m_pCurrentSceneManager->setShadowTextureSize(1024);
	m_OgreEngine.m_pCurrentSceneManager->setShadowFarDistance(1000);

	m_WindForce = Vector3(0, -100, 0);
	m_WindSpeed = 1;

	m_WindForceBySystem[0] = Vector3(-1, 0.1, 1);
	m_WindForceBySystem[1] = Vector3(1, -0.1, 1);
	m_WindForceBySystem[2] = Vector3(0, -0.1, 1);
	m_WindForceBySystem[3] = Vector3(0, 0.1, -1);

	addParticleSystems();
}

void CScenePetitPot :: Detach(void)
{
	CSceneBase::Detach();
	removeParticleSystems();
}

void CScenePetitPot :: removeParticleSystems(void)
{
	for (int i = 1; i <= 4; ++i)
	{
		m_pSceneNode->removeAndDestroyChild("Leaf" + StringConverter::toString(i));
		m_OgreEngine.m_pCurrentSceneManager->destroyParticleSystem("Leaf" + StringConverter::toString(i));
	}
}

void CScenePetitPot :: addParticleSystems(void)
{
	ParticleSystem *system;

	system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Leaf1", "openmove/petitpot");
	system->getEmitter(0)->setPosition(Vector3(229.597, 67.5505, -391.933));
	m_pSceneNode->createChildSceneNode("Leaf1")->attachObject(system);

	system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Leaf2", "openmove/petitpot");
	system->getEmitter(0)->setPosition(Vector3(-598, 96.4, 54.4));
	m_pSceneNode->createChildSceneNode("Leaf2")->attachObject(system);

	system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Leaf3", "openmove/petitpot");
	system->getEmitter(0)->setPosition(Vector3(470, 194, -152));
	m_pSceneNode->createChildSceneNode("Leaf3")->attachObject(system);

	system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Leaf4", "openmove/petitpot");
	system->getEmitter(0)->setPosition(Vector3(187.374, 61, 522));
	m_pSceneNode->createChildSceneNode("Leaf4")->attachObject(system);
}

void CScenePetitPot :: updateParticleSystems(void)
{
	for (int i = 1; i <= 4; ++i)
	{
		ParticleSystem *system = m_OgreEngine.m_pCurrentSceneManager->getParticleSystem("Leaf" + StringConverter::toString(i));
		ParticleAffector *affector = system->getAffector(1);
		//affector->setParameter("force_vector", StringConverter::toString(m_WindForce));
		Vector3 final = m_WindForceBySystem[i - 1] * m_WindSpeed;
		affector->setParameter("force_vector", StringConverter::toString(final));
		m_OgreEngine.setDebugText("force_vector" + StringConverter::toString(i) + ": " + StringConverter::toString(final));
	}
}

void CScenePetitPot :: processEvents(void)
{
	CSceneBase::processEvents();

	for (TEvents::iterator It = m_Events.begin(); It != m_Events.end(); ++It)
	{
		switch (It->m_Packet.eventid)
		{
			case SOpenMoveDisplayPacket::e_PP_IncWind:
			{
				++m_WindForce.x;
				break;
			}
			case SOpenMoveDisplayPacket::e_PP_DecWind:
			{
				--m_WindForce.x;
				break;
			}
			case SOpenMoveDisplayPacket::e_PP_SetWind:
			{
#if 0
				Vector3 windSpeed = StringConverter::parseVector3(It->m_Packet.params);
				SimpleSpline spline;
				spline.addPoint(m_WindForce);
				spline.addPoint(windSpeed);
				Real time = It->m_pTimer->getSeconds() / It->m_Packet.duree;
				m_WindForce = spline.interpolate(time / 2.0f);

				m_OgreEngine.setDebugText("time: " + StringConverter::toString(time));
#endif
			}
			case SOpenMoveDisplayPacket::e_PP_SetWindForce:
			{
				//m_WindSpeed = StringConverter::parseReal(It->m_Packet.params);
				m_WindSpeed = 600.0f * (It->m_Packet.user_speed / 1.5f);

				m_OgreEngine.setDebugText("m_WindSpeed: " + StringConverter::toString(m_WindSpeed));
			}
			default:
			{
				break;
			}
		}
	}
}